package la.iok.aone.monitor.youtube.schedule;

import la.iok.aone.monitor.youtube.mapper.YoutubeLinkMapper;
import la.iok.aone.monitor.youtube.model.YoutubeLink;
import la.iok.aone.monitor.youtube.task.CheckYoutubeLink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Youtube链接检测定时器，用于定时检测Youtube链接的有效性。
 * @author bunco
 * @date 2018年6月5日 10时20分
 * @version 1.0
 */
@Component
public class CheckSchedule {
    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 从数据库获取每一页数据的间隔（单位：秒）
     * 默认值：3
     */
    @Value("${config.monitor.fetch.each.page.interval:3}")
    private int interval;
    /**
     * 从数据库获取一页数据的数量
     * 默认值：50
     */
    @Value("${config.monitor.fetch.each.page.size:50}")
    private int pageSize;
    @Autowired
    private YoutubeLinkMapper youtubeLinkMapper;
    @Autowired
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private CheckYoutubeLink checkYoutubeLink;

    /**
     * 每隔一段时间，将数据库中所有链接取出来，生成检测任务，扔到线程池中执行。
     * 注意：为cron表达式设置默认值时
     */
    @Scheduled(cron = "${config.monitor.schedule.cron:10 * * * * ?}")
    public void checkYoutubeLink(){
        logger.info("checkYoutubeLink =====>>>>> cron: {}",
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        int offset = 0;
        int maxRecords = this.youtubeLinkMapper.count();
        while(offset < maxRecords) {
            List<YoutubeLink> list = this.youtubeLinkMapper.getAllByPage(offset, pageSize);
            logger.debug("{}", list);
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    checkYoutubeLink.check(list);
                }
            });
            offset += pageSize;
            try {
                // 休眠几秒，避免大量任务同时丢进线程池，导致任务被丢弃。
                Thread.sleep(interval * 1000);
            } catch (InterruptedException e) {
                logger.error("", e);
            }
        }
    }
}
